#include <arpa/inet.h>
#include <algorithm>
#include <numeric>
#include <sstream>
#include <stdexcept>
#include <string>
#include "fastrpc/rpc/coder/fastpb_protocol.hpp"
#include "fastrpc/rpc/common/rpc_util.hpp"

namespace fastrpc::rpc::detail {

class FastRpcCodec {
public:
    FastRpcCodec() {}

    std::string encode(const FastPBProtocol& protocol) {
        // 计算包的总长度
        size_t pk_len = 2 + 24 + protocol.m_msg_id.length() + protocol.m_method_name.length()
                        + protocol.m_err_info.length() + protocol.m_pb_data.length();

        std::string result;
        result.resize(pk_len);

        char* tmp = result.data();

        // 1. 写入 PB_START
        *tmp = FastPBProtocol::PB_START;
        tmp++;

        // 2. 写入总长度 (包长度，网络字节序)
        uint32_t pk_len_net = htonl(pk_len);
        memcpy(tmp, &pk_len_net, sizeof(pk_len_net));
        tmp += sizeof(pk_len_net);

        // 3. 写入 MsgID 长度 (网络字节序)
        uint32_t msg_id_len = protocol.m_msg_id.length();
        uint32_t msg_id_len_net = htonl(msg_id_len);
        memcpy(tmp, &msg_id_len_net, sizeof(msg_id_len_net));
        tmp += sizeof(msg_id_len_net);

        // 4. 写入 MsgID
        if (msg_id_len > 0) {
            memcpy(tmp, protocol.m_msg_id.data(), msg_id_len);
            tmp += msg_id_len;
        }

        // 5. 写入 Method Name 长度 (网络字节序)
        uint32_t method_name_len = protocol.m_method_name.length();
        uint32_t method_name_len_net = htonl(method_name_len);
        memcpy(tmp, &method_name_len_net, sizeof(method_name_len_net));
        tmp += sizeof(method_name_len_net);

        // 6. 写入 Method Name
        if (method_name_len > 0) {
            memcpy(tmp, protocol.m_method_name.data(), method_name_len);
            tmp += method_name_len;
        }

        // 7. 写入 Error Code (网络字节序)
        uint32_t err_code_net = htonl(protocol.m_err_code);
        memcpy(tmp, &err_code_net, sizeof(err_code_net));
        tmp += sizeof(err_code_net);

        // 8. 写入 Error Info 长度 (网络字节序)
        uint32_t err_info_len = protocol.m_err_info.length();
        uint32_t err_info_len_net = htonl(err_info_len);
        memcpy(tmp, &err_info_len_net, sizeof(err_info_len_net));
        tmp += sizeof(err_info_len_net);

        // 9. 写入 Error Info
        if (err_info_len > 0) {
            memcpy(tmp, protocol.m_err_info.data(), err_info_len);
            tmp += err_info_len;
        }

        // 10. 写入 Protobuf 数据
        if (protocol.m_pb_data.length() > 0) {
            memcpy(tmp, protocol.m_pb_data.data(), protocol.m_pb_data.length());
            tmp += protocol.m_pb_data.length();
        }

        // 11. 写入 Checksum (网络字节序)
        uint32_t check_sum_net = htonl(1);  // 假设校验和为 1
        memcpy(tmp, &check_sum_net, sizeof(check_sum_net));
        tmp += sizeof(check_sum_net);

        // 12. 写入 PB_END
        *tmp = FastPBProtocol::PB_END;

        // 最后返回编码后的结果
        return result;
    }

    util::RpcResult<FastPBProtocol> decode(std::span<char> buf) {
        if (buf.empty()) {
            return std::unexpected{util::RpcError(util::RpcError::InvalidFormat)};
        }

        FastPBProtocol protocol;

        // 1. 查找 PB_START
        size_t start_pos
            = std::find(buf.begin(), buf.end(), FastPBProtocol::PB_START) - buf.begin();
        if (start_pos == buf.size()) {
            return std::unexpected{util::RpcError(util::RpcError::InvalidFormat)};
        }

        // 2. 读取包长度（网络字节序），计算协议的总长度
        if (start_pos + 1 + sizeof(uint32_t) > buf.size()) {
            return std::unexpected{util::RpcError(util::RpcError::InvalidFormat)};
        }

        protocol.m_pk_len = util::read_u32(
            buf.subspan(start_pos + 1, sizeof(uint32_t)));  // 包长度从 PB_START 后面开始
        if (protocol.m_pk_len > buf.size()) {
            return std::unexpected{util::RpcError(util::RpcError::InvalidFormat)};
        }

        // 3. 解析各字段，从包长度后开始
        size_t offset = start_pos + 1 + sizeof(uint32_t);

        // 4. 解析 MsgID 长度（网络字节序）
        if (offset + sizeof(uint32_t) > buf.size()) {
            return std::unexpected{util::RpcError(util::RpcError::InvalidFormat)};
        }
        protocol.m_msg_id_len = util::read_u32(buf.subspan(offset, sizeof(uint32_t)));
        offset += sizeof(uint32_t);

        // 5. 解析 MsgID
        if (protocol.m_msg_id_len > 0) {
            if (offset + protocol.m_msg_id_len > buf.size()) {
                return std::unexpected{util::RpcError(util::RpcError::InvalidFormat)};
            }
            protocol.m_msg_id.assign(buf.subspan(offset, protocol.m_msg_id_len).data(),
                                     protocol.m_msg_id_len);
            offset += protocol.m_msg_id_len;
        }

        // 6. 解析 Method Name 长度（网络字节序）
        if (offset + sizeof(uint32_t) > buf.size()) {
            return std::unexpected{util::RpcError(util::RpcError::InvalidFormat)};
        }
        protocol.m_method_name_len = util::read_u32(buf.subspan(offset, sizeof(uint32_t)));
        offset += sizeof(uint32_t);

        // 7. 解析 Method Name
        if (protocol.m_method_name_len > 0) {
            if (offset + protocol.m_method_name_len > buf.size()) {
                return std::unexpected{util::RpcError(util::RpcError::InvalidFormat)};
            }
            protocol.m_method_name.assign(buf.subspan(offset, protocol.m_method_name_len).data(),
                                          protocol.m_method_name_len);
            offset += protocol.m_method_name_len;
        }

        // 8. 解析 ErrCode（错误码）
        if (offset + sizeof(uint32_t) > buf.size()) {
            return std::unexpected{util::RpcError(util::RpcError::InvalidFormat)};
        }
        protocol.m_err_code = util::read_u32(buf.subspan(offset, sizeof(uint32_t)));
        offset += sizeof(uint32_t);

        // 9. 解析 ErrInfo 长度（网络字节序）
        if (offset + sizeof(uint32_t) > buf.size()) {
            return std::unexpected{util::RpcError(util::RpcError::InvalidFormat)};
        }
        protocol.m_err_info_len = util::read_u32(buf.subspan(offset, sizeof(uint32_t)));
        offset += sizeof(uint32_t);

        // 10. 解析 ErrInfo（错误信息）
        if (protocol.m_err_info_len > 0) {
            if (offset + protocol.m_err_info_len > buf.size()) {
                return std::unexpected{util::RpcError(util::RpcError::InvalidFormat)};
            }
            protocol.m_err_info.assign(buf.subspan(offset, protocol.m_err_info_len).data(),
                                       protocol.m_err_info_len);
            offset += protocol.m_err_info_len;
        }

        // 11. 解析 Protobuf 数据
        int pb_data_len = protocol.m_pk_len - protocol.m_method_name_len - protocol.m_msg_id_len
                          - protocol.m_err_info_len - 2 - 24;  // 总长度减去各个部分的长度
        if (offset + pb_data_len > buf.size()) {
            return std::unexpected{util::RpcError(util::RpcError::InvalidFormat)};
        }
        protocol.m_pb_data.assign(buf.subspan(offset, pb_data_len).data(), pb_data_len);
        offset += pb_data_len;

        // 12. 校验和（Checksum）
        if (offset + sizeof(uint32_t) > buf.size()) {
            return std::unexpected{util::RpcError(util::RpcError::InvalidFormat)};
        }

        uint32_t checksum = util::read_u32(buf.subspan(offset, sizeof(uint32_t)));
        offset += sizeof(uint32_t);

        // 校验和验证（假设在编码时你固定为 1）
        if (checksum != 1) {  // 校验和不匹配
            return std::unexpected{util::RpcError(util::RpcError::InvalidFormat)};
        }

        // 13. 校验结束符 PB_END
        if (buf[buf.size() - 1] != FastPBProtocol::PB_END) {
            return std::unexpected{util::RpcError(util::RpcError::InvalidFormat)};
        }

        protocol.parse_success = true;  // 表示解析成功
        return protocol;                // 返回解析后的协议数据
    }

    // 编码 FastPBProtocol 为字节流
    // std::string encode(FastPBProtocol& protocol) {
    //     std::stringstream ss;

    //     // 计算总包长度 (m_pk_len)
    //     size_t total_size
    //         = 1 +                                  // PB_START (1 byte)
    //           4 +                                  // m_pk_len (4 bytes)
    //           4 +                                  // m_err_code (4 bytes)
    //           4 + protocol.m_msg_id.size() +       // m_msg_id_len (4 bytes) + m_msg_id
    //           4 + protocol.m_err_info.size() +     // m_err_info_len (4 bytes) + m_err_info
    //           4 + protocol.m_method_name.size() +  // m_method_name_len (4 bytes) + m_method_name
    //           protocol.m_pb_data.size() +          // Protobuf data size
    //           1;                                   // PB_END (1 byte)

    //     protocol.m_pk_len = total_size;  // 设置包的总长度

    //     // 写入开始符
    //     ss.put(FastPBProtocol::PB_START);

    //     // 写入包总长度
    //     std::array<char, 4> len_bytes;
    //     util::write_u32(protocol.m_pk_len, std::span<char>(len_bytes));
    //     ss.write(len_bytes.data(), len_bytes.size());

    //     // 写入错误码
    //     util::write_u32(protocol.m_err_code, std::span<char>(len_bytes));
    //     ss.write(len_bytes.data(), len_bytes.size());

    //     // 写入 MsgID 长度和 MsgID
    //     uint32_t msg_id_len = protocol.m_msg_id.size();
    //     util::write_u32(msg_id_len, std::span<char>(len_bytes));
    //     ss.write(len_bytes.data(), len_bytes.size());
    //     ss.write(protocol.m_msg_id.c_str(), msg_id_len);

    //     // 写入错误信息长度和错误信息
    //     uint32_t err_info_len = protocol.m_err_info.size();
    //     util::write_u32(err_info_len, std::span<char>(len_bytes));
    //     ss.write(len_bytes.data(), len_bytes.size());
    //     ss.write(protocol.m_err_info.c_str(), err_info_len);

    //     // 写入方法名长度和方法名
    //     uint32_t method_name_len = protocol.m_method_name.size();
    //     util::write_u32(method_name_len, std::span<char>(len_bytes));
    //     ss.write(len_bytes.data(), len_bytes.size());
    //     ss.write(protocol.m_method_name.c_str(), method_name_len);

    //     // 写入 Protobuf 数据
    //     ss.write(protocol.m_pb_data.c_str(), protocol.m_pb_data.size());

    //     // 写入结束符
    //     ss.put(FastPBProtocol::PB_END);

    //     return ss.str();
    // }

    // // 解码字节流为 FastPBProtocol
    // util::RpcResult<FastPBProtocol> decode(std::span<char> buf) {
    //     if (buf.empty()) {
    //         return std::unexpected{util::RpcError(util::RpcError::InvalidFormat)};
    //     }

    //     FastPBProtocol protocol;

    //     // 校验开始符
    //     size_t start_pos
    //         = std::find(buf.begin(), buf.end(), FastPBProtocol::PB_START) - buf.begin();
    //     if (start_pos == buf.size()) {
    //         return std::unexpected{util::RpcError(util::RpcError::InvalidFormat)};
    //     }

    //     // 读取整包长度（包含开始符和结束符）
    //     protocol.m_pk_len
    //         = util::read_u32(buf.subspan(start_pos + 1, 4));  // 包长度从 PB_START 后面开始
    //     if (protocol.m_pk_len != buf.size()) {
    //         return std::unexpected{util::RpcError(util::RpcError::InvalidFormat)};
    //     }

    //     size_t offset = start_pos + 5;  // 从第 5 字节开始解析

    //     // 解析错误码
    //     protocol.m_err_code = util::read_u32(buf.subspan(offset, 4));
    //     offset += 4;

    //     // 解析 MsgID
    //     protocol.m_msg_id_len = util::read_u32(buf.subspan(offset, 4));
    //     offset += 4;

    //     // 确保 MsgID 长度在合理范围
    //     if (protocol.m_msg_id_len > (buf.size() - offset)) {
    //         return std::unexpected{util::RpcError(util::RpcError::InvalidFormat)};
    //     }
    //     protocol.m_msg_id.assign(buf.subspan(offset, protocol.m_msg_id_len).data(),
    //                              protocol.m_msg_id_len);
    //     offset += protocol.m_msg_id_len;

    //     // 解析错误信息
    //     protocol.m_err_info_len = util::read_u32(buf.subspan(offset, 4));
    //     offset += 4;

    //     // 确保错误信息长度在合理范围
    //     if (protocol.m_err_info_len > (buf.size() - offset)) {
    //         return std::unexpected{util::RpcError(util::RpcError::InvalidFormat)};
    //     }
    //     protocol.m_err_info.assign(buf.subspan(offset, protocol.m_err_info_len).data(),
    //                                protocol.m_err_info_len);
    //     offset += protocol.m_err_info_len;

    //     // 解析方法名
    //     protocol.m_method_name_len = util::read_u32(buf.subspan(offset, 4));
    //     offset += 4;

    //     // 确保方法名长度在合理范围
    //     if (protocol.m_method_name_len > (buf.size() - offset)) {
    //         return std::unexpected{util::RpcError(util::RpcError::InvalidFormat)};
    //     }
    //     protocol.m_method_name.assign(buf.subspan(offset, protocol.m_method_name_len).data(),
    //                                   protocol.m_method_name_len);
    //     offset += protocol.m_method_name_len;

    //     // 解析 Protobuf 数据
    //     // size_t pb_data_len = protocol.m_pk_len - offset - 1;  // 去除结束符
    //     int pb_data_len = protocol.m_pk_len - protocol.m_method_name_len - protocol.m_msg_id_len
    //                       - protocol.m_err_info_len - 2 - 24;  // 总长度减去各个部分的长度

    //     if (pb_data_len > (buf.size() - offset)) {
    //         return std::unexpected{util::RpcError(util::RpcError::InvalidFormat)};
    //     }
    //     protocol.m_pb_data.assign(buf.subspan(offset, pb_data_len).data(), pb_data_len);
    //     offset += pb_data_len;

    //     // 校验结束符
    //     if (buf[buf.size() - 1] != FastPBProtocol::PB_END) {
    //         return std::unexpected{util::RpcError(util::RpcError::InvalidFormat)};
    //     }

    //     protocol.parse_success = true;
    //     return protocol;
    // }
};

}  // namespace fastrpc::rpc::detail
